import re
import json
import os.path

proj_name = "RTT"
config_path = '.vscode/bconf.json'
output_inc_path = '.vscode/c_cpp_properties.json'

default_cStandard = "c99"
default_cppStandard = "c++11"
intelliSenseMode = "windows-gcc-arm"

def get_includePath(file_ctx:str):
    include_path_pattern = r'<listOptionValue builtIn="false" value="&quot;\$\{workspace_loc://\$\{ProjName\}(.*?)\}&quot;" />'  # 匹配目标句子
    # 正则表达匹配
    raw_path = re.findall(include_path_pattern, file_ctx);
    replace_path = [s.replace('//', '/') for s in raw_path]
    filtered_path = [item for item in replace_path if item != '/.']

    # 补充前后缀
    json_path = ['${workspaceFolder}'+ s + '/**' for s in filtered_path]
    
    # 补充根目录
    json_path.insert(0,"${workspaceFolder}/**")

    # 排除link.lds项
    json_path = [item for item in json_path if "link.lds" not in item]

    # 去重
    json_path = list(set(json_path))
    
    json_path.sort()

    for path in json_path:
        print(path);

    return json_path

def get_defines(file_ctx:str):
    # define 匹配
    defines_pattern_pre = r'<option[^>]*?name="Defined symbols \(-D\)"[^>]*?valueType="definedSymbols"[^>]*?>\s*(.*?)\s*</option>'
    defines_pattern = r'<listOptionValue[^>]*?value="([^"]*?)"[^>]*?/>'
    raw_defines_pre = re.findall(defines_pattern_pre, file_ctx, re.DOTALL)
    for s in raw_defines_pre:
        define_item = re.findall(defines_pattern, s)

    # for defines in define_item:
    #     print(defines)
    define_item.insert(0, "_UNICODE")
    define_item.insert(0, "UNICODE")
    define_item.insert(0, "_DEBUG")
    
    return define_item


if __name__ == "__main__":
    if os.path.exists(config_path):
        with open(config_path,"r") as file:
            config = json.load(file)
            compilerPath = config["compilerPath"]
            cStandard = config["cStandard"]
            cppStandard = config["cppStandard"]
            # intelliSenseMode = config["intelliSenseMode"]
    else:
        compilerPath = input("编译器路径: ")
        cStandard = input("c标准: ")
        cppStandard = input("cpp标准: ")
        # intelliSenseMode = input("intelliSenseMode: ")
        config = {"compilerPath":compilerPath, "cStandard":cStandard, "cppStandard":cppStandard}
        
        if not os.path.exists(".vscode/"):
            os.mkdir(".vscode")
        with open(config_path,'w') as config_file:
            json.dump(config, config_file, indent="\t")

    with open('../.cproject', 'r') as file:
        file_ctx = file.read()
    inlcude_path = get_includePath(file_ctx)
    defines = get_defines(file_ctx)

    print()
    print("c:", cStandard)
    print("cpp:", cppStandard)
    print("project name:", proj_name)
    print("compilerPath:", compilerPath)
    print("intelliSenseMode:", intelliSenseMode)

    configurations = {"name":proj_name, "includePath":inlcude_path, "defines":defines, "compilerPath":compilerPath, "cStandard":cStandard, "cppStandard":cppStandard, "intelliSenseMode":intelliSenseMode}

    properties_json = {"configurations":[configurations], "version": 4}

    if not os.path.exists(".vscode/"):
        os.mkdir(".vscode")
    with open(output_inc_path, 'w') as target_file:
        json.dump(properties_json, target_file, indent="\t")

    print(">>>>>>>>>\nGenerate c_cpp_properties.json at:", output_inc_path)